package com.example.software.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.software.dto.CompanyRegisterDTO;
import com.example.software.dto.LoginDTO;
import com.example.software.dto.WorkerRegisterDTO;
import com.example.software.entity.CompanyInfo;
import com.example.software.entity.User;
import com.example.software.entity.WorkerInfo;
import com.example.software.mapper.CompanyInfoMapper;
import com.example.software.mapper.UserMapper;
import com.example.software.mapper.WorkerInfoMapper;
import com.example.software.service.UserService;
import com.example.software.util.JwtUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.HashMap;

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    private CompanyInfoMapper companyInfoMapper;

    @Autowired
    private WorkerInfoMapper workerInfoMapper;

    @Autowired
    private BCryptPasswordEncoder passwordEncoder;

    @Autowired
    private JwtUtil jwtUtil;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean registerCompany(CompanyRegisterDTO registerDTO) {
        log.info("开始企业注册流程，注册信息：{}", registerDTO);
        
        // 检查用户名是否已存在
        if (checkUsernameExists(registerDTO.getUsername())) {
            log.warn("用户名已存在：{}", registerDTO.getUsername());
            throw new RuntimeException("用户名已存在");
        }

        try {
            // 创建用户
            User user = new User();
            user.setUsername(registerDTO.getUsername());
            user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
            user.setUserType("company");
            save(user);
            log.info("用户基本信息创建成功，用户ID：{}", user.getId());

            // 创建企业信息
            CompanyInfo companyInfo = new CompanyInfo();
            companyInfo.setUserId(user.getId());
            companyInfo.setCompanyName(registerDTO.getCompanyName());
            companyInfo.setCompanyAddress(registerDTO.getCompanyAddress());
            companyInfo.setCompanyType(registerDTO.getCompanyType());
            companyInfo.setLegalName(registerDTO.getLegalName());
            companyInfo.setLegalPhone(registerDTO.getLegalPhone());
            companyInfo.setLegalIdCard(registerDTO.getLegalIdCard());
            companyInfo.setBankAccount(registerDTO.getBankAccount());
            companyInfoMapper.insert(companyInfo);
            log.info("企业详细信息创建成功，企业ID：{}", companyInfo.getId());

            return true;
        } catch (Exception e) {
            log.error("企业注册失败", e);
            throw new RuntimeException("注册失败，请稍后再试");
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean registerWorker(WorkerRegisterDTO registerDTO) {
        log.info("开始零工注册流程，注册信息：{}", registerDTO);
        
        try {
            // 检查用户名是否已存在
            if (checkUsernameExists(registerDTO.getUsername())) {
                log.warn("用户名已存在：{}", registerDTO.getUsername());
                throw new RuntimeException("用户名已存在");
            }
            
            log.info("零工用户名检查通过，开始创建用户");
            
            // 创建用户
            User user = new User();
            user.setUsername(registerDTO.getUsername());
            // 记录密码长度，帮助调试（不记录实际密码）
            log.info("开始加密密码，原始密码长度：{}", registerDTO.getPassword().length());
            user.setPassword(passwordEncoder.encode(registerDTO.getPassword()));
            user.setUserType("worker");
            
            // 保存用户记录
            log.info("保存用户基本信息");
            boolean userSaved = save(user);
            if (!userSaved) {
                log.error("保存用户基本信息失败");
                throw new RuntimeException("保存用户信息失败");
            }
            log.info("用户基本信息保存成功，用户ID：{}", user.getId());
            
            // 创建零工信息
            WorkerInfo workerInfo = new WorkerInfo();
            workerInfo.setUserId(user.getId());
            workerInfo.setName(registerDTO.getName());
            workerInfo.setPhone(registerDTO.getPhone());
            workerInfo.setIdCard(registerDTO.getIdCard());
            workerInfo.setBankAccount(registerDTO.getBankAccount());
            workerInfo.setSkillType(registerDTO.getSkillType());
            
            log.info("保存零工详细信息");
            int result = workerInfoMapper.insert(workerInfo);
            if (result <= 0) {
                log.error("保存零工详细信息失败");
                throw new RuntimeException("保存零工详细信息失败");
            }
            log.info("零工详细信息保存成功，零工ID：{}", workerInfo.getId());
            
            return true;
        } catch (Exception e) {
            log.error("零工注册失败", e);
            throw new RuntimeException("注册失败：" + e.getMessage());
        }
    }

    @Override
    public String login(LoginDTO loginDTO) {
        // 根据用户名查询用户
        User user = getByUsername(loginDTO.getUsername());
        if (user == null) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 验证密码
        if (!passwordEncoder.matches(loginDTO.getPassword(), user.getPassword())) {
            throw new RuntimeException("用户名或密码错误");
        }

        // 生成token
        return jwtUtil.generateToken(user.getId(), user.getUsername(), user.getUserType());
    }

    @Override
    public User getByUsername(String username) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, username);
        return getOne(queryWrapper);
    }

    /**
     * 检查用户名是否已存在
     * @param username 用户名
     * @return 是否存在
     */
    private boolean checkUsernameExists(String username) {
        return count(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, username)) > 0;
    }

    @Override
    public User getUserById(Long userId) {
        log.debug("根据ID获取用户 - 用户ID: {}", userId);
        return getById(userId);
    }
    
    @Override
    public User getUserByUsername(String username) {
        log.debug("根据用户名获取用户 - 用户名: {}", username);
        return lambdaQuery().eq(User::getUsername, username).one();
    }
    
    @Override
    public Map<Long, String> getUsernamesByIds(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return new HashMap<>();
        }
        
        List<User> users = list(new LambdaQueryWrapper<User>()
                .in(User::getId, userIds));
        
        return users.stream()
                .collect(Collectors.toMap(
                    User::getId, 
                    User::getUsername,
                    (existing, replacement) -> existing  // 如果有重复的键，保留第一个
                ));
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createAdmin(LoginDTO adminDTO) {
        log.info("开始创建管理员账号: {}", adminDTO.getUsername());
        
        // 检查用户名是否已存在
        if (checkUsernameExists(adminDTO.getUsername())) {
            log.warn("用户名已存在：{}", adminDTO.getUsername());
            throw new RuntimeException("用户名已存在");
        }
        
        try {
            // 创建管理员用户
            User adminUser = new User();
            adminUser.setUsername(adminDTO.getUsername());
            adminUser.setPassword(passwordEncoder.encode(adminDTO.getPassword()));
            adminUser.setUserType("admin");
            save(adminUser);
            
            log.info("管理员账号创建成功，ID: {}", adminUser.getId());
            return true;
        } catch (Exception e) {
            log.error("管理员账号创建失败", e);
            throw new RuntimeException("创建管理员账号失败: " + e.getMessage());
        }
    }
    
    @Override
    public List<User> getAllUsers() {
        return list();
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(Long userId) {
        User user = getById(userId);
        if (user == null) {
            throw new RuntimeException("用户不存在");
        }
        
        // 不允许删除管理员账号
        if ("admin".equals(user.getUserType())) {
            throw new RuntimeException("不允许删除管理员账号");
        }
        
        // 删除用户关联信息
        if ("company".equals(user.getUserType())) {
            // 删除企业信息
            companyInfoMapper.delete(new LambdaQueryWrapper<CompanyInfo>()
                .eq(CompanyInfo::getUserId, userId));
        } else if ("worker".equals(user.getUserType())) {
            // 删除零工信息
            workerInfoMapper.delete(new LambdaQueryWrapper<WorkerInfo>()
                .eq(WorkerInfo::getUserId, userId));
        }
        
        // 删除用户
        return removeById(userId);
    }
} 